#ifndef GLUESH_H_
#define GLUESH_H_

typedef struct feature feature_t;
/* the maximum number of keypoint NN candidates to check during BBF search */
#define KDTREE_BBF_MAX_NN_CHKS 200
/* threshold on squared ratio of distances between NN and 2nd NN */
#define NN_SQ_DIST_RATIO_THR 0.49
#define EG_MIN_SIFT_MATCHES 20
#define EG_MIN_RANSAC_MATCHES 12
/** default threshold on keypoint contrast |D(x)| */
#define EG_SIFT_CONTR_THR 0.04
/** default threshold on keypoint ratio of principle curvatures */
#define EG_SIFT_CURV_THR 10

/**
 * Debug function to print a matrix.
 * @param A the matrix to be printed.
 */
void PrintMat(CvMat *A);

/**
 * Estimate the new matrix size based on max e min coordinates of new_dim matrix, and its displacement.
 * @param size1 size of image1
 * @param size2 size of image2
 * @param H_inv the inverted tranform
 * @param width the estimated new width
 * @param height the estimated new height
 * @param dispx translation into x axis
 * @param dispy translation into y axis
 */
void egGetSizeDisp(CvSize size1, CvSize size2, CvMat *new_dim, int *width, int *height, int *dispx, int *dispy);

/**
 * Normalizes a array of coordinates with dimension 3xn.
 * @param src source matrix (3xn)
 * @param dst destination matrix (3xn)
 */
void egNorm(CvMat* src, CvMat* dst);

/**
 * Normalizes a array of coordinates with dimension 3x3.
 * @param src the input matrix (3x3)
 * @param dst the normalized matrix (3x3)
 */
void egNorm3x3(CvMat* src, CvMat* dst);

/**
 * Guess the new image size after the H_inv transforming.
 * @param size the original size
 * @param H_inv the affine transformation to be applied
 * @param new_dim the returned matrix with new dimensions to the 4 
 *        coordinates of the transformed rectangle.
 */
void egGuessNewDim(CvSize size, CvMat* H_inv, CvMat* new_dim);

/**
 * Build a displacement (translation) matrix
 * @param dispx displacement in x axis
 * @param dispy displacement in y axis
 * @return the 3x3 transform matrix
 */
void egBuildH_disp(int dispx, int dispy, CvMat* H_disp);

/**
 * Add the two tranforms: perspective and displacement - traslation.
 * @param H_inv the perspective transform (3x3)
 * @param H_disp the translation matrix (3x3) only.
 * @return the compound transform matrix.
 */
void egBuildH_trans(CvMat* H_inv, CvMat* H_disp, CvMat* H_trans);

/**
 * Glues two images based on the features set (feat1 and feat2). Returns a new image with the adjusted size.
 * @param img1 the 'left' image
 * @param feat1 features extracted from img1
 * @param n1 number of features from img1
 * @param img2 the 'right' image
 * @param feat2 the features extracted from img2
 * @param newimg the processed image and glued image
 * @returns 1 when succeed; 0 otherwise
 */
int egGlue(IplImage *img1, feature_t *feat1, int n1, IplImage *img2, feature_t *feat2, IplImage **newimg);

/**
 * Find features using the SIFT algorithtms.
 * @param img1 the 'left' image
 * @param feat1 returns the features from img1
 * @param n1 returns the number of features im img1
 * @param img2 the 'right' image
 * @param feat2 the features from img2
 * @returns 1 when suceed; 0 otherwise
 */
int egFindFeatures(IplImage *img1, feature_t **feat1, int *n1, IplImage *img2, feature_t **feat2);

/**
 * Computes a mask that will define what from xformed2 will be copied to the newimg. 
 * @param xformed1 the img1 after transforming.
 * @param xformed2 the img2 after transforming.  
 */
IplImage* egComputeMask(IplImage *xformed1, IplImage *xformed2);

#endif /*GLUESH_H_*/
